﻿using MES.Desktop.Common;
using MES.Desktop.Entities;
using MES.Desktop.IService;
using MES.Desktop.SystemModule.Models;
using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace MES.Desktop.SystemModule.ViewModels
{
    public class RoleViewModel : PageViewModelBase
    {
        private RoleEntity[] _origRoles;
        public ObservableCollection<RoleModel> Roles { get; set; } =
            new ObservableCollection<RoleModel>();

        private RoleModel _currentRole;

        public RoleModel CurrentRole
        {
            get { return _currentRole; }
            set
            {
                SetProperty<RoleModel>(ref _currentRole, value);


                if (value == null) return;

                SetMenuStatus(Menus, value.MenuIds);
                Application.Current.Dispatcher.Invoke(() =>
                {
                    Funcs.Clear();
                });

                LoadUsers(value.UserIds);
            }
        }


        public ObservableCollection<MenuModel> Menus { get; set; } =
            new ObservableCollection<MenuModel>();

        public ObservableCollection<FuncModel> Funcs { get; set; } =
            new ObservableCollection<FuncModel>();

        public ObservableCollection<UserModel> Users { get; set; } =
            new ObservableCollection<UserModel>();

        private bool isSyncSelect;
        private bool _isSelectAll;

        public bool IsSelectAll
        {
            get { return _isSelectAll; }
            set
            {
                SetProperty<bool>(ref _isSelectAll, value);

                if (isSyncSelect) return;
                isSyncSelect = true;

                foreach (var depart in Roles)
                    depart.IsSelected = value;

                isSyncSelect = false;
            }
        }

        private string _menuName;

        public string MenuName
        {
            get { return _menuName; }
            set { SetProperty<string>(ref _menuName, value); }
        }


        public DelegateCommand<MenuModel> MenuItemClickedCommand { get; set; }
        public DelegateCommand SelectUserCommand { get; set; }
        public DelegateCommand SaveCommand { get; set; }
        IRoleService _roleService;
        IEventAggregator _eventAggregator;
        IDialogService _dialogService;
        IMenuService _menuService;
        IUserService _userService;
        GlobalValues _globalValues;

        public RoleViewModel(
            IRegionManager regionManager,
            IEventAggregator eventAggregator,
            IRoleService roleService,
            IDialogService dialogService,
            IMenuService menuService,
            IUserService userService,
            GlobalValues globalValues)
            : base(regionManager)
        {
            this.PageTitle = "系统角色与权限";

            _roleService = roleService;
            _eventAggregator = eventAggregator;
            _dialogService = dialogService;
            _menuService = menuService;
            _userService = userService;
            _globalValues = globalValues;

            MenuItemClickedCommand = new DelegateCommand<MenuModel>(DoMenuItemClick);
            SelectUserCommand = new DelegateCommand(DoSelcetUser);
            SaveCommand = new DelegateCommand(DoSave);
            this.Refresh();
        }

        public override void Refresh()
        {
            Roles.Clear();

            _eventAggregator.GetEvent<LoadingEvent>()
               .Publish("正在加载角色....");

            Task.Run(() =>
            {
                try
                {
                    _origRoles = _roleService.GetAllRoles(this.SearchKey);

                    foreach (var role in _origRoles)
                    {
                        var model = new RoleModel
                        {
                            RoleId = role.RoleId,
                            RoleName = role.RoleName,
                            RoleDesc = role.RoleDesc,
                            // 角色列表子项---菜单ID---功能
                            MenuIds = role.Menus.Select(m => m.MenuId.ToString()).ToList(),
                            UserIds = role.Users.Select(u => u.UserId).ToList(),
                        };

                        model.PropertyChanged += (se, ev) =>
                        {
                            if (isSyncSelect) return;
                            isSyncSelect = true;

                            if (ev.PropertyName == "IsSelected")
                                this.IsSelectAll = Roles.All(f => f.IsSelected);

                            isSyncSelect = false;
                        };

                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            Roles.Add(model);
                        });

                        //if (Roles.Count > 0)
                        //    CurrentRole = Roles[0];
                    }

                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        if (Roles.Count > 0)
                            CurrentRole = Roles[0];
                        Menus.Clear();
                    });
                    // 初始化显示所有菜单 
                    var menus = _menuService.GetAllMenus();
                    FillMenus(Menus, null, menus.ToList());


                    // 根据当前默认角色  配置菜单的选择项
                    // 根据当前默认角色  配置用户列表
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "提示");
                }
                finally
                {
                    _eventAggregator.GetEvent<LoadingEvent>()
                        .Publish("");
                }
            });
        }

        void FillMenus(ObservableCollection<MenuModel> menus,
            MenuModel parent, List<Entities.MenuEntity> origMenus, bool expandedNode = true)
        {
            var sub = origMenus.Where(m => m.ParentId == (parent == null ? "-1" : parent.MenuId))
                .ToList();

            if (sub.Count() > 0)
            {
                foreach (Entities.MenuEntity item in sub)
                {
                    MenuModel model = new MenuModel
                    {
                        IsSelected = CurrentRole.MenuIds.Contains(item.MenuId),
                        MenuId = item.MenuId,
                        MenuHeader = item.MenuHeader,
                        MenuIcon = item.MenuIcon,
                        TargetView = item.TargetView,
                        ParentId = (parent == null ? "0" : parent.MenuId),
                        IsExpanded = expandedNode,
                        Parent = parent,

                        FuncIds = item.Funcs,
                        FuncNames = item.FuncNames
                    };
                    model.PropertyChanged += (se, ev) =>
                    {
                        if (model.Parent != null && model.IsSelected)
                            model.Parent.IsSelected = true;

                        // 菜单发生选择变化的时候，更新权限菜单ID
                        List<string> ids = new List<string>();
                        var _1_ids = Menus.Select(m => new
                        {
                            selected = m.IsSelected,
                            id = m.MenuId,
                            sub_ids = m.Children.Where(m => m.IsSelected).Select(m => m.MenuId.ToString()).ToArray()
                        })
                        .Where(m => m.selected)
                        .Select(m =>
                        {
                            ids.Add(m.id.ToString());
                            ids.AddRange(m.sub_ids);

                            return m.id;
                        }).ToList();

                        CurrentRole.MenuIds = ids;
                    };
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        menus.Add(model);
                    });

                    FillMenus(model.Children, model, origMenus);
                }

                if (menus.Count > 0)
                {
                    menus[menus.Count - 1].IsLastChild = true;
                }
            }
        }

        private void SetMenuStatus(ObservableCollection<MenuModel> menus, List<string> mids)
        {
            foreach (var item in menus)
            {
                item.IsSelected = mids.Contains(item.MenuId);
                if (item.Children != null && item.Children.Count > 0)
                {
                    SetMenuStatus(item.Children, mids);
                }
            }
        }

        private void LoadUsers(List<int> uids)
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                Users.Clear();
            });
            var us = _userService.GetUsersByIds(uids.ToArray());
            foreach (var u in us)
            {
                UserModel user = new UserModel
                {
                    UserId = u.userId,
                    UserName = u.userName,
                    RealName = u.realName,
                    UserIcon = $"{_globalValues.ServerHost}/api/File/img/" + u.eIcon
                };

                Application.Current.Dispatcher.Invoke(() =>
                {
                    Users.Add(user);
                });
            }
            Application.Current.Dispatcher.Invoke(() =>
            {
                Users.Add(new UserModel { });
            });
        }


        public override void DoModify(object obj)
        {
            DialogParameters ps = new DialogParameters();
            ps.Add("model", obj);

            _dialogService.ShowDialog("ModifyRoleView", ps, result =>
            {
                // 判断子窗口的返回状态，如果OK，刷新当前页面，否则不管
                if (result.Result == ButtonResult.OK)
                {
                    this.Refresh();
                }
            });
        }

        public override void DoBatchDelete()
        {
            var ids = Roles.Where(r => r.IsSelected)
                          .Select(r => r.RoleId)
                          .ToArray();
            this.Delete(ids);
        }

        public override void DoDelete(object obj)
        {
            this.Delete(new int[] { (obj as RoleModel).RoleId });
        }

        void Delete(int[] ids)
        {
            try
            {
                if (MessageBox.Show("是否确定删除？", "提示", MessageBoxButton.YesNo) ==
                    MessageBoxResult.Yes)
                {
                    // 物理删除
                    _roleService.Delete(ids);

                    MessageBox.Show("删除完成！", "提示");

                    this.Refresh();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "提示");
            }

        }

        private void DoMenuItemClick(MenuModel menu)
        {
            MenuName = menu.Parent == null ?
                "" : menu.Parent.MenuHeader + "/";

            MenuName += menu.MenuHeader;

            Funcs.Clear();

            if (menu.Parent == null) return;

            // 
            string? use_funcs = _origRoles.FirstOrDefault(r => r.RoleId == CurrentRole.RoleId)?
                  .Menus?.FirstOrDefault(m => m.MenuId.ToString() == menu.MenuId)?
                  .MenuFuncs;

            string[] ids = menu.FuncIds.Split(',');
            string[] names = menu.FuncNames.Split(",");

            for (int i = 0; i < ids.Length; i++)
            {
                FuncModel fm = new FuncModel
                {
                    IsSelected = use_funcs == null ? false : use_funcs.Contains(ids[i]),
                    FuncId = int.Parse(ids[i]),
                    FuncName = names[i]
                };

                fm.PropertyChanged += (se, ev) =>
                {
                    if (ev.PropertyName == "IsSelected")
                    {
                        // 找出权限组下的功能属性   进行修改
                        var rfs = _origRoles.FirstOrDefault(r => r.RoleId == CurrentRole.RoleId);
                        if (rfs.Menus == null)
                            rfs.Menus = new List<RoleMenuEntity>();

                        var mfs = rfs.Menus.FirstOrDefault(m => m.MenuId.ToString() == menu.MenuId);
                        if (mfs == null)
                        {
                            rfs.Menus.Add(new RoleMenuEntity { MenuId = int.Parse(menu.MenuId) });
                            mfs = rfs.Menus[0];
                        }


                        var fs = Funcs.Where(f => f.IsSelected);
                        // 可用的功能列表
                        mfs.MenuFuncs = string.Join(",", fs.Select(f => f.FuncId).ToList());

                        menu.IsSelected = true;
                    }
                }
            ;

                Funcs.Add(fm);
            }

        }

        private void DoSelcetUser()
        {
            DialogParameters dps = new DialogParameters();
            dps.Add("uids", CurrentRole.UserIds);
            dps.Add("rid", CurrentRole.RoleId);
            //_rid = CurrentRole.RoleId;
            _dialogService.ShowDialog("SelectUserView", dps, result =>
            {
                if (result.Result == ButtonResult.OK)
                {
                    // 获取选择的用户信息
                    // 插入用户列表 ，并且更新角色的用户
                    //this.Refresh();
                    //_rid = 0;

                    var ids = result.Parameters.GetValue<List<int>>("ids");
                    CurrentRole.UserIds = new List<int>(ids);

                    LoadUsers(CurrentRole.UserIds);
                }
            });
        }

        private void DoSave()
        {
            // 取出当前角色下的所有数据
            // 分别提交到数据
            try
            {
                var r = _origRoles.FirstOrDefault(r => r.RoleId == CurrentRole.RoleId);
                if (r == null) return;
                // R-M-F
                List<RoleMenuEntity> rms = new List<RoleMenuEntity>();
                foreach (var mid in CurrentRole.MenuIds)
                {
                    var m = r.Menus.FirstOrDefault(m => m.MenuId.ToString() == mid);

                    rms.Add(new RoleMenuEntity
                    {
                        RoleId = CurrentRole.RoleId,
                        MenuId = int.Parse(mid),
                        MenuFuncs = m?.MenuFuncs
                    });
                }
                if (rms.Count > 0)
                    _roleService.UpdateRoleMenus(rms.ToArray());

                // R-U
                List<RoleUserEntity> rus = new List<RoleUserEntity>();
                foreach (var uid in CurrentRole.UserIds)
                    rus.Add(new RoleUserEntity
                    {
                        RoleId = CurrentRole.RoleId,
                        UserId = uid
                    });
                if (rus.Count > 0)
                    _roleService.UpdateRoleUsers(rus.ToArray());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "提示");
            }
        }
    }
}
